import { Inject, Injectable } from '@nestjs/common'
import { Redis } from 'ioredis'

@Injectable()
export class RedisService {
  constructor(
    @Inject('REDIS_CLIENT')
    private readonly redis: Redis
  ) { }
  //string 存键值
  async set(key: string, value: any, ttl?: number): Promise<string | [Error, unknown][]> {
    // 使用 Redis 的 EXPIRE 命令设置过期时间（单位为秒）
    if (ttl) {
      return await this.redis.multi().set(key, value).expire(key, ttl).exec()
    }
    return await this.redis.set(key, value)
  }

  //获取键
  async get(key): Promise<string> {
    return await this.redis.get(key)
  }

  //自增1
  async incr(key): Promise<number> {
    return await this.redis.incr(key)
  }

  async incrby(key, value): Promise<number> {
    return await this.redis.incrby(key, value)
  }

  //自减1
  async decr(key): Promise<number> {
    return await this.redis.decr(key)
  }

  async decrby(key, value): Promise<number> {
    return await this.redis.decrby(key, value)
  }

  //删除键
  async del(key): Promise<number> {
    return await this.redis.del(key)
  }

  //存 hash值
  async setHashData(key: string, data: Record<string, string>): Promise<'OK'> {
    this.redis.expire(key, 12 * 60 * 60)
    return this.redis.hmset(key, data);
  }

  async getHashData(key: string, type: 'all' | string): Promise<Record<string, string> | string | null> {
    if (type == 'all') {
      return await this.redis.hgetall(key)
    }
    try {
      return await this.redis.hget(key, type)
    } catch (error) {
      console.error('Error getting hash field:', error.message);
      return null
    }

  }

  //删除hash
  async deleteEntireHash(key: string): Promise<void> {
    const fields = await this.redis.hkeys(key);
    for (const field of fields) {
      await this.redis.hdel(key, field);
    }
  }

  //获取键过期时间

  async getKeyTTL(key) {
    try {
      const ttlInSeconds = await this.redis.ttl(key);
      if (ttlInSeconds === -1) {
        console.log(`Key "${key}" does not exist or has no associated expire.`);
        return 0
      } else {
        return ttlInSeconds
      }
    } catch (error) {
      console.error('Error while getting TTL:', error);
    }
  }

}


